package org.hepeng.workx.spring.cloud.netflix.eureka.server;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;


/**
 * @author he peng
 */
public class EurekaServerEventListener implements ApplicationListener {

    private Map<Class<? extends ApplicationEvent> , List<EurekaServerEventConsumer>> eventConsumers = new ConcurrentHashMap<>();
    private EurekaEventConsumerExecutor executor;

    public EurekaServerEventListener(EurekaEventConsumerExecutor executor) {
        this.executor = executor;
    }

    public EurekaServerEventListener(EurekaEventConsumerExecutor executor , Map<Class<? extends ApplicationEvent>, List<EurekaServerEventConsumer>> eventConsumers) {
        this(executor);
        this.eventConsumers.putAll(eventConsumers);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        List<EurekaServerEventConsumer> eventConsumers = this.eventConsumers.get(event.getClass());
        if (CollectionUtils.isNotEmpty(eventConsumers)) {
            this.executor.execute(event , eventConsumers);
        }
    }

    public void registerEventConsumer(Class<? extends ApplicationEvent> key , EurekaServerEventConsumer value) {
        List<EurekaServerEventConsumer> eventConsumers = this.eventConsumers.get(key);
        if (Objects.isNull(eventConsumers)) {
            eventConsumers = new ArrayList<>();
            eventConsumers.add(value);
            this.eventConsumers.put(key , eventConsumers);
        } else {
            eventConsumers.add(value);
            this.eventConsumers.put(key , eventConsumers);
        }
    }

    public void registerEventConsumer(Class<? extends ApplicationEvent> key , List<EurekaServerEventConsumer> value) {
        List<EurekaServerEventConsumer> eventConsumers = this.eventConsumers.get(key);
        if (Objects.isNull(eventConsumers)) {
            this.eventConsumers.put(key , value);
        } else {
            eventConsumers.addAll(value);
            this.eventConsumers.put(key , eventConsumers);
        }
    }
}
